<?php

if(!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 *
 * Ova klasa pronalazi odgovarajuci red cijene ( minPs i minNg ), za trazenu sezonu, za sobu za svaki dan bukinga posebno ( zbog preklapanja sezona )
 * Umanjuje broj osoba ukoliko su osobe djeca sa popustom 100% ( free of charge )
 *
 *
 * //This class finds correspoding total prices for number of buuking days
 * //Example: for 6 days finds per day=10, it calculates selling_price = 6*10=60
 *
 * Inputs are
 *
 * duration booking: Checkin, Checkout,
 * number of persons: Nr adults, Nr childrens
 *
 * It also find corresponding season for period of buking
 *
 * @author ivankukic
 */
class price_row_finder
{

    protected $checkin;
    protected $checkout;
    protected $nradults;
    protected $nrchildrens;
    protected $childsage=array();
    protected $nrpersons;
    protected $nrnights;
    protected $room_id;

    public function __construct()
    {

        $this->CI=&get_instance();
        $this->CI->load->model("rooms_model");
        $this->CI->load->model("prices_model");
        $this->CI->load->model("objects_has_seasons_model");
        $this->CI->load->model("seasons_model");
        $this->CI->load->model("availability_model");
        $this->CI->load->helper("calculate_days");
        $this->CI->load->helper("percent");
        $this->CI->load->library('prices/discount_finder');
        $this->CI->load->helper('date');

    }

    /**
     *
     * Show error message
     * @param $str error string
     */
    public function throwError($str)
    {
        echo $str;
        exit();

    }

    public function getCheckin()
    {
        return $this->checkin;

    }

    public function setCheckin($checkin)
    {
        $this->checkin=strtotime($checkin);

    }

    public function getCheckout()
    {
        return $this->checkout;

    }

    public function setCheckout($checkout)
    {
        $this->checkout=strtotime($checkout);

    }

    public function getNradults()
    {
        return $this->nradults;

    }

    public function setNradults($nradults)
    {
        $this->nradults=(int) $nradults;

    }

    public function getNrchildrens()
    {
        return $this->nrchildrens;

    }

    public function setNrchildrens($nrchildrens)
    {
        $this->nrchildrens=(int) $nrchildrens;

    }

    public function getChildsAge()
    {
        return $this->childsage; //return array

    }

    public function setChildsAge($age)
    {
        if(count($this->childsage) + 1 > $this->nrchildrens)
            $this->throwError("Count of ages and childres mismach");
        array_push($this->childsage, (int) $age);

    }

    public function clearChildsAge()
    {
        $this->childsage=array();

    }

    public function getNrpersons()
    {
        return $this->nrpersons;

    }

    public function setNrpersons($nrpersons)
    {
        $this->nrpersons=(int) $nrpersons;

    }

    public function getNrnights()
    {
        return $this->nrnights;

    }

    public function setNrnights($nrnights)
    {
        $this->nrnights=$nrnights;

    }

    public function getRoom_id()
    {
        return $this->room_id;

    }

    public function setRoom_id($room_id)
    {
        $this->room_id=$room_id;

    }

    private function _check_settings()
    {

        // check in check
        if(!isset($this->checkin))
            $this->throwError("Please specify check in.");

        // check out check
        if(!isset($this->checkout))
            $this->throwError("Please specify check out.");

        // check if Adults person exists
        if(!isset($this->nradults) || !$this->nradults > 0)
            $this->throwError("Please add at least one Adlut person.");

        // check if roomID is set
        if(!isset($this->room_id))
            $this->throwError("Please specify room ID.");

        // check if childage is set
        if(isset($this->nrchildrens)):

            for($z=0; $z < $this->nrchildrens; $z++):
                if(!isset($this->childsage[$z]))
                    $this->throwError('Please specify childs age for each child');
            endfor;

        endif;

    }

    public function find_room_booking_price()
    {

        $this->_check_settings();

        $stop=$this->find_stop_booking();

        //TODO add check release period method

        $release_stop= $this->check_release_period();


        if($stop || $release_stop)
        {
            return array();
        }
        $row_price=$this->find_room_price();

        if(empty($row_price))
            return array();

        $row_price=$this->rooms_caluclation_and_discounts($row_price);

        if(empty($row_price))
            return array();

        return $row_price;

    }

    public function check_release_period()
    {
        $season_ID=$this->CI->objects_has_seasons_model->find_active_seasons_by_room($this->room_id);
        $release_period = $this->CI->seasons_model->get_periods_release_period($season_ID, $this->checkin);
        // check if checkin - today > release period


        $date_now = now();
        //echo(date('d.m.Y.H.G.s',$date_now));
        $dmy = date('d.m.Y', $date_now) . " 00:00:00";
        //echo("release period: " . $release_period . " period " .  (($this->checkin - strtotime($dmy))/(60*60*24) - 1));
        //echo '<br>';
        //echo 'now ' . $dmy . " checkin " . date('d.m.Y.H.G.s',$this->checkin);
        //echo $this->getCheckin();


        if($release_period <= (($this->checkin - strtotime($dmy))/(60*60*24)) - 1)
            return false;
        return true;

    }

    public function find_room_price()
    {
        $this->_check_settings();

        // find prices
        $room_prices=$this->CI->prices_model->find_all_prices($this->room_id, $this->checkin, $this->checkout);


        // set nr persons and nr nights and row_price
        $this->setNrpersons($this->nradults + $this->nrchildrens);

        // find discounts if any and decrese nrpersons if discount is 100(percent %)
        $this->set_nr_persons_if_discounts_100();

        $this->setNrnights(calculateDays($this->checkin, $this->checkout));
        $row_price=array();

        // we ordered results
        // start by compering by lowest value for min_person & min_nights

        foreach($room_prices as $price):

            // pronalazi odgovarajuci red cijene za minPS i minNG ***

            if(($this->nrpersons >= (int) $price['selling_min_person']) && ($this->nrnights >= (int) $price['selling_min_ng'])):

                // set prices to 0
                $price['selling_price']=0;
                $price['net_price']=0;
                $price['margin_price']=0;

                // find corresponding season
                $season_ID=$this->CI->objects_has_seasons_model->find_active_seasons_by_room($this->room_id);

                // find corresponding price for each day of booking
                for($i=1; $i <= $this->nrnights; $i++):
                    $day=prepareEncreseSearchDate($this->checkin, $i);

                    $period_ID=$this->CI->seasons_model->find_active_period_again($season_ID, $day);


                    // find seling price for that period
                    $sel_periods=$this->CI->strparse->find_lang_in_string($price['selling_periods'], $period_ID);
                    $net_periods=$this->CI->strparse->find_lang_in_string($price['net_periods'], $period_ID);
                    $margin_periods=$this->CI->strparse->find_lang_in_string($price['margin_periods'], $period_ID);

                    // if price is not defined,
                    // return empty array,
                    // it will me removed from search result
                    if(floatval($sel_periods) == 0)
                        return array();

                    $price['selling_price'] += floatval($sel_periods);
                    $price['net_price'] += floatval($net_periods);
                    $price['margin_price'] += floatval($margin_periods);
                    //log_message('info', date('d.m.Y', $day));
                endfor;

                // overvrite row if condition mach
                $row_price=$price;

            endif;
        endforeach;

        /**
        Return data set
        [ID] => 3
        [selling_min_person] => 1
        [selling_min_ng] => 1
        [selling_periods] => <!--:1-->150<!--:-->
        [net_min_person] =>
        [net_min_ng] =>
        [net_periods] =>
        [margin_min_person] =>
        [margin_min_ng] =>
        [margin_periods] =>
        [rooms_ID] => 2
        [selling_price] => 150
        [net_price] =>
        [margin_price] =>
         *
         */
        /**
         * If empty price row, room price is not defined for this number of person/s
         *
         * Exapmle: "Double Room is Not Defined For Singe Use"
         *
         */
        if(empty($row_price))
            return array();
        else
            return $row_price;

    }

    public function rooms_caluclation_and_discounts($row_price)
    {

        $this->_check_settings();

        // find discounts and total price for selling billing type
        $room=$this->CI->rooms_model->find_id($this->room_id);

        // do calculation
        switch($room['selling_billing_type_ID'])
        {

            case 2: // per person/night
                $selling_price=$this->calc_total_perpersons_night_price($row_price['selling_price']);
                $net_price=$this->calc_total_perpersons_night_price($row_price['net_price']);
                $margin_price=$selling_price - $net_price;
                break;

            case 3: // per item per day
                $selling_price=$row_price['selling_price'];
                $net_price=$row_price['net_price'];
                $margin_price=$selling_price - $net_price;
                break;

            case 5: // per room/night
                $selling_price=$row_price['selling_price'];
                $net_price=$row_price['net_price'];
                $margin_price=$selling_price - $net_price;
                break;
        }

        $row_price['selling_total']=$selling_price;
        $row_price['net_total']=$net_price;
        $row_price['margin_total']=$margin_price;

        return $row_price;

    }

    public function calc_total_perpersons_night_price($selling_price)
    {

        $this->_check_settings();

        $total=0;

        // do Children first
        // apply discounts on children price
        if(isset($this->childsage) && count($this->childsage) > 0)
            foreach($this->childsage as $age) :

                $this->CI->discount_finder->setRoom_id($this->room_id);
                $this->CI->discount_finder->setChildAge($age);

                // TODO set nr adults for discount_finder lib
                $this->CI->discount_finder->setNradults($this->nradults);


                $discount=(int) $this->CI->discount_finder->find_discount();

                // calculate discount
                if($discount != 0)
                {
                    $perc=find_percent($discount, $selling_price);
                    $total += $selling_price - $perc;
                }
                else
                {
                    $total += $selling_price;
                }

            endforeach;

        // do Adults
        $total += $selling_price * $this->nradults;

        return $total;

    }

    public function set_nr_persons_if_discounts_100()
    {

        $this->_check_settings();

        if(isset($this->childsage) && count($this->childsage) > 0)
            foreach($this->childsage as $age) :
                $this->CI->discount_finder->setRoom_id($this->room_id);
                $this->CI->discount_finder->setChildAge($age);

                // TODO check next line if condition for nr_adults changes
                $this->CI->discount_finder->setNradults($this->nradults);

                $discount=(int) $this->CI->discount_finder->find_discount();
                $free_of_charge=(int) 100;
                if($discount === $free_of_charge):
                    $this->nrpersons-=1;
                endif;

            endforeach;

    }

    // TODO - CHECK LOGIC FOR STOP BOOKING COMPARATION
    public function find_stop_booking()
    {

        $this->_check_settings();

        $stop=$this->CI->availability_model->list_by_room($this->room_id);

        if(empty($stop))
            return FALSE;

        foreach($stop as $st):

            if($this->checkin > $st['start'] && $this->checkin < $st['end'])
                return TRUE;

            if($this->checkout > $st['start'] && $this->checkout < $st['end'])
                return TRUE;

            if($this->checkin == $st['start'] && $this->checkout == $st['end'])
                return TRUE;

            if($this->checkin == $st['start'])
                return TRUE;

            if($this->checkout == $st['end'])
                return TRUE;

            if($this->checkin < $st['start'] && $this->checkout > $st['end'])
                return TRUE;

        endforeach;

        return FALSE;

    }

}

?>